/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package es.unavarra.mti.iws.model;

import es.unavarra.mti.iws.Manager;
import es.unavarra.mti.iws.logic.editor.Selectable;
import es.unavarra.mti.iws.logic.undoredo.AddEntry;
import es.unavarra.mti.iws.logic.undoredo.DeleteEntries;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;

/**
 *
 * @author Asier
 */
public class Model {
    private Manager manager;
    private ArrayList<Node> nodes;
    private ArrayList<Link> links;
    private ArrayList<Event> events;


    public Model() {
        nodes = new ArrayList<Node>();
        links = new ArrayList<Link>();
        events = new ArrayList<Event>();
    }

    public void setManager(Manager manager) {
        this.manager = manager;
    }

    

    public ArrayList<Event> getEvents() {
        return events;
    }

    public ArrayList<Link> getLinks() {
        return links;
    }

    public ArrayList<Node> getNodes() {
        return nodes;
    }

    public void setEvents(ArrayList<Event> events) {
        this.events = events;
    }

    public void setLinks(ArrayList<Link> links) {
        this.links = links;
    }

    public void setNodes(ArrayList<Node> nodes) {
        this.nodes = nodes;
    }

    public synchronized void reAddItems(){
        synchronized(nodes){
            synchronized(links){
                for(Node n : nodes){
                    manager.getEngine().addNode(n.getId(),n.getType()==Node.TYPE_IMOTE?"Imote2":"Iris");
                }
                for(Link l : links){
                    manager.getEngine().addLink(l.getNodeSource().getId(), l.getNodeTarget().getId());
                }
            }
        }
    }


    public synchronized void deleteEntries(ArrayList<Selectable> entries) {
        synchronized(entries){
            ArrayList<Selectable> entriesPlusLinks = new ArrayList<Selectable>(entries.size());
            HashMap<Link,Link> linksTreated = new HashMap<Link, Link>();
            for(Selectable s : entries){
                if (s instanceof Link){
                    linksTreated.put((Link)s, (Link)s);
                }else if(s instanceof Node){
                    synchronized(links){
                        Node n = (Node)s;
                        for(Link l : links){
                            if(l.getNodeSource() == n || l.getNodeTarget() == n){
                                linksTreated.put(l, l);
                            }
                        }
                    }
                    entriesPlusLinks.add(s);
                }else{
                    entriesPlusLinks.add(s);
                }
                for(Link l : linksTreated.keySet()){
                    entriesPlusLinks.add(l);
                }

                Collections.reverse(entriesPlusLinks);
                
            }
            DeleteEntries op = new DeleteEntries(this, entriesPlusLinks);
            op.redo();
            manager.getUndo().addOp(op);
        }
    }

    public synchronized void addEntry(Selectable entry) {
        if (entry instanceof Link){
            Link cl = (Link)entry;
            if (cl.getNodeSource() == cl.getNodeTarget()) { return; }
            synchronized(links){
                for(Link l : links){
                    if((l.getNodeSource() == cl.getNodeSource() && l.getNodeTarget() == cl.getNodeTarget())||
                       (l.getNodeTarget() == cl.getNodeSource() && l.getNodeSource() == cl.getNodeTarget())){
                        return;
                    }
                }
            }
        }
        AddEntry op = new AddEntry(this, entry);
        op.redo();
        manager.getUndo().addOp(op);
    }


    public void add(Selectable selectable) {
        if (selectable instanceof Node){
            Node n = (Node)selectable;
            nodes.add(n);
            manager.getEngine().addNode(n.getId(),n.getType()==Node.TYPE_IMOTE?"Imote2":"Iris");
        }else if (selectable instanceof Link){
            Link n = (Link)selectable;
            links.add(n);
             manager.getEngine().addLink(n.getNodeSource().getId(), n.getNodeTarget().getId());
        } else if (selectable instanceof Event) {
            Event n = (Event)selectable;
            events.add(n);
        }
    }
  
    public void remove(Selectable selectable) {
     
            if (selectable instanceof Node){
                Node n = (Node)selectable;
                if(nodes.remove(n)){
                    manager.getEngine().delNode(n.getId());
                }
            }else if (selectable instanceof Link){
                Link n = (Link)selectable;
                if(links.remove(n)){
                    manager.getEngine().delLink(n.getNodeSource().getId(), n.getNodeTarget().getId());
                }
            } else if (selectable instanceof Event) {
                Event n = (Event)selectable;
                events.remove(n);
            }
        
    }


    
}
